package com.danton.auth.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.danton.auth.service.UserService;
import com.danton.auth.service.impl.UserServiceImpl;
import com.danton.auth.token.LoginToken;
import com.danton.auth.validator.RegisterValidator;
import com.danton.common.Config;
import com.danton.common.bean.CommonResponse;
import com.danton.common.exception.UserAlreadyExistException;
import com.danton.framework.BaseController;
import com.danton.model.BsAdminModel;
import com.danton.model.BsRoleModel;
import com.jfinal.aop.Before;
import com.jfinal.kit.PropKit;

public class AuthController extends BaseController {
	protected static final Logger logger = LoggerFactory.getLogger(AuthController.class);
	private UserService userService = enhance(UserServiceImpl.class);//支持事务处理
	/**
	 * 注册
	 */
	@Before(RegisterValidator.class)
	public void register() {
		String user_name = getPara("user_name");
		String password = getPara("password");//此处密码已经做过摘要处理
		String ip_address= getPara("ip_address","127.0.0.1");
		String access_key_id = getPara("access_key_id");
		String access_key_secret = getPara("access_key_secret");
		String role_code = getPara("role_code");
		Properties pro = PropKit.use(Config.accessFileName).getProperties();
		if(pro==null){
			renderJson(CommonResponse.buildResponse(600, "内部错误"));
			return;
		}else{
			String local_key_secret = pro.getProperty(access_key_id);
			if(local_key_secret==null||!local_key_secret.equals(access_key_secret)){
				renderJson(CommonResponse.buildResponse(601, "access_key 错误"));
				return;
			}
		}

		try {
			BsAdminModel adminModel = new BsAdminModel();
			adminModel.set("user_name", user_name).set("password", password).set("ip_address", ip_address).set("source", access_key_id);
			userService.register(adminModel,role_code,access_key_id);
		} catch (UserAlreadyExistException e) {
			e.printStackTrace();
			renderJson(CommonResponse.buildResponse(602, "用户已经存在"));
			return;
		}
		CommonResponse responeStatus = CommonResponse.buildResponse();
		responeStatus.getBody().put("user_name", user_name);
		renderJson(responeStatus);
	}
	
	/**
	 * 登陆
	 */
	public void login() {
		CommonResponse responeStatus = CommonResponse.buildResponse();
		
		String user_name = getPara("user_name");
		String password = getPara("password");
		String access_key_id = getPara("access_key_id");
		String sessionID = "";
		
		Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

		// 2、得到SecurityManager实例 并绑定给SecurityUtils
		org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
		
		SecurityUtils.setSecurityManager(securityManager);

		// 3、得到Subject及创建用户名/密码身份验证Token（即用户身份/凭证）
		Subject subject = SecurityUtils.getSubject();
		if(subject.isAuthenticated()){
//			Session session = subject.getSession();
//			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd mm:ss");
//			Map<String,Object> result = new HashMap<>();
//			result.put("login_time", sdf.format(session.getStartTimestamp()));
//			result.put("lastAccess_time", sdf.format(session.getLastAccessTime()));
			sessionID = (String)subject.getSession().getId();
		}else{
			LoginToken token = new LoginToken(user_name, password,access_key_id);
			try {
				// 4、登录，即身份验证
				subject.login(token);
				sessionID = (String)subject.getSession().getId();
			} catch (UnknownAccountException e) {
				e.printStackTrace();
				// 5、身份验证失败
				responeStatus = CommonResponse.buildResponse(610, e.getMessage());
				renderJson(responeStatus);
				return;
			}catch (IncorrectCredentialsException e) {
				e.printStackTrace();
				// 5、身份验证失败
				responeStatus = CommonResponse.buildResponse(611, e.getMessage());
				renderJson(responeStatus);
				return;
			}
			BsAdminModel adminModel = userService.findByUserName(user_name);
			//返回sessionID及用户名,用户ID
			responeStatus.getBody().put("OBSIDIAN_SESSION", sessionID);
			responeStatus.getBody().put("user_name", user_name);
			responeStatus.getBody().put("user_id", String.valueOf(adminModel.getInt("id")));
			renderJson(responeStatus);
		}
		logger.debug("=======session_id========:"+sessionID);
	}
	
	/**
	 * 注销登陆
	 */
	public void logout() {
		CommonResponse responeStatus = CommonResponse.buildResponse();
		String session_id = getRequest().getHeader("OBSIDIAN_SESSION");
		Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
		// 2、得到SecurityManager实例 并绑定给SecurityUtils
		org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
		SecurityUtils.setSecurityManager(securityManager);

		// 3、得到Subject及创建用户名/密码身份验证Token（即用户身份/凭证）
		//Subject subject = SecurityUtils.getSubject();
		Subject subject = new Subject.Builder().sessionId(session_id).buildSubject();
		if(subject.isAuthenticated()||subject.isRemembered()){
			subject.logout();
		}
		renderJson(responeStatus);
	}
	
	/**
	 * 查询权限
	 */
	public void checkPermission() {
		CommonResponse responeStatus = CommonResponse.buildResponse();
		String session_id = getRequest().getHeader("OBSIDIAN_SESSION");
		String permission = getPara("permission");
		Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
		
		// 2、得到SecurityManager实例 并绑定给SecurityUtils
		org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
		SecurityUtils.setSecurityManager(securityManager);

		// 3、得到Subject及创建用户名/密码身份验证Token（即用户身份/凭证）
		//Subject subject = SecurityUtils.getSubject();
		Subject subject = new Subject.Builder().sessionId(session_id).buildSubject();
		if(subject.isAuthenticated()){
			if(subject.isPermitted(permission)){
				renderJson(responeStatus);
				return;
			}else{
				responeStatus = CommonResponse.buildResponse(620, "没有权限");
			}
		}else{
			responeStatus = CommonResponse.buildResponse(621, "请重新登录");
		}
		renderJson(responeStatus);
	}
	
	public void listRoles() {
		CommonResponse responeStatus = CommonResponse.buildResponse();
		String session_id = getRequest().getHeader("OBSIDIAN_SESSION");
		Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
		
		// 2、得到SecurityManager实例 并绑定给SecurityUtils
		org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
		SecurityUtils.setSecurityManager(securityManager);

		// 3、得到Subject及创建用户名/密码身份验证Token（即用户身份/凭证）
		//Subject subject = SecurityUtils.getSubject();
		Subject subject = new Subject.Builder().sessionId(session_id).buildSubject();
		if(subject.isAuthenticated()){
			BsAdminModel adminModel = (BsAdminModel) subject.getPrincipal(); // 得到用户名
			List<BsRoleModel> roles = userService.findRolesByUserID(adminModel.getInt("id"));
			List<String> roleCode = new ArrayList<String>();
			for (BsRoleModel bsRoleModel : roles) {
				roleCode.add(bsRoleModel.getStr("code"));
			}
			responeStatus.getBody().put("roles", roleCode);
		}else{
			responeStatus = CommonResponse.buildResponse(621, "请重新登录");
		}
		renderJson(responeStatus);
	}
}

